package util
{
	import mx.collections.ArrayCollection;
	import vo.userInfoVo;

	public class tvmUtil
	{
		/////////////////////////////////////////////
		// Command..
		/////////////////////////////////////////////		
		public static function comp(com:String, form:userInfoVo):Number {		
			
			//var dec_places = 2;\						
			//var pb = form.pb[0].checked?1:0;			 
			
			
			if(form.iy == 0) {				
				//form.iy = 1; // test silver
			}
			
			
			var pb:Number   = 	form.pb; // beginning = 1, end = 0
			var pv:Number 	= 	form.pv;
			var fv:Number 	= 	form.fv;
			var np:Number 	= 	form.n;
			var pmt:Number 	=	form.pmt;
			var ir:Number 	=	form.iy/100.0;
			var db:String	= 	form.sDanBockri;
			var rtnVal:Number;
			switch(com) {
				case 'pv':
					pv = comp_pv(np,ir,pmt,fv,pb);
					rtnVal = pv;
					break;
				case 'pt':
				case 'fv':					
					fv = comp_fv(np, ir, pmt, pv, pb, db);
					rtnVal = fv;
					break;
				case 'urd': // 거치 : 달로 계산시킴, ir은 연이율 4%일때 4를 그대로 넣는다.					
					fv = comp_Unredeemed(np, ir, pmt, pv, pb, db);
					rtnVal = fv;
					break;				
				case 'np':
					np = comp_np(ir,pmt,fv,pv,pb);
					rtnVal = np;
					break;
				case 'pmt':
					pmt = comp_pmt(np,ir,fv,pv,pb);
					rtnVal = pmt;
					break;
				case 'iy':
					ir = comp_iy(np,ir,pmt,pv,fv,pb);
					rtnVal = ir;
					break;
				case 'loc':
					rtnVal = -1;
					break;
			}
			return rtnVal;
		} // function comp
		
		/////////////////////////////////////////////
		// get pv
		/////////////////////////////////////////////
		public static function comp_pv(np:Number, ir:Number, pmt:Number ,fv:Number, pb:Number):Number
		{
			var pv:Number;
			if(ir == 0.0) {
				pv = - fv - np * pmt;
			}
			else {
				var qa:Number = Math.pow(1 + ir,-np);
				var qb:Number = Math.pow(1 + ir,np);
				pv = - qa * (fv + ((-1 + qb) * pmt * (1 + ir * pb))/ir);
			}
			return pv;
		}
		
		/////////////////////////////////////////////
		// get fv
		/////////////////////////////////////////////
		public static function comp_Unredeemed(np:Number, ir:Number, pmt:Number, pv:Number,pb:Number, db:String="B"):Number
		{
			var ac:ArrayCollection = new ArrayCollection();
			if(db==null) {
				db = 'B';
			}
			if(db == 'B') {
				ac = srUtil.srUnredeemedCompound(pv, np, ir, "M");	
			}else{
				ac = srUtil.srUnredeemedSimple(pv, np, ir, "M");
			}
			
			var fv:Number;
			if(ac != null && ac.length > 0) {
				fv = ac.getItemAt(ac.length-1).val;	
			} else {
				fv = 0;
			}
			return fv;
		}
			
		/////////////////////////////////////////////
		// get fv
		/////////////////////////////////////////////
		public static function comp_fv(np:Number, ir:Number, pmt:Number, pv:Number,pb:Number, db:String="B"):Number
		{
			var fv:Number;
			if(db == null) {
				db = "B";
			}
			if(db == "D") {
				//pv = pv*-1;//silver
				
				// pmt가 0이면 pv에대한 fv 계산 (거치)
				if(pmt == 0){
					fv = pv * (1+ir * np);	
				}
				// pmt가 0보다 크면 적립금에 대한 fv 계산 (적립)
				else if(pmt >= 0){
					fv = (pmt * np) + (pmt * ir) * (np*(np+1)/2);
					//fv = (pmt * np) + (pmt * np*(np+1)/2 * ir/12);
					fv = fv * -1;					
				}

				//fv = pv * (1+ir * np);
			} 
			else if(db == "B") {
				pv = pv*-1;//silver
				if(ir == 0.0) {
					fv = - np * pmt - pv;
				}
				else {
					var q:Number = Math.pow(1+ir,np);
					fv = - q * pv - (((-1 + q) * pmt * (1 + ir * pb))/ir);
				}	
			}

			return fv;
		}
		
		/////////////////////////////////////////////
		// get pmt
		/////////////////////////////////////////////
		public static function comp_pmt( np:Number,  ir:Number, fv:Number,  pv:Number, pb:Number):Number
		{
			if(np==0){
				return 0;
			}
			var pmt:Number = 0;
			if(ir == 0.0) {
				if(np != 0.0) {
					pmt = - (fv + pv)/np;
				}
			}
			else {
				var q:Number = Math.pow(1+ir,np);
				pmt = - (ir * (fv + (q * pv)))/((-1 + q) * (1 + ir * pb));
			}
			return pmt;
		}
		
		/////////////////////////////////////////////
		// get np
		/////////////////////////////////////////////
		public static function comp_np( ir:Number,  pmt:Number,  fv:Number,  pv:Number, pb:Number):Number
		{
			
			if(pv == 0 || fv == 0 || ir == 0) {
				return 0;
			}
			
			var np:Number = 0;
			fv = fv * -1; // silver
			if(ir == 0.0) {
				if(pmt != 0.0) {
					np = - (fv + pv)/pmt;
				}
			}
			else { // ir != 0
				var terma:Number = -fv * ir + pmt + ir * pmt * pb;
				var termb:Number = pmt + ir * pv + ir * pmt * pb;
				np = Math.log(terma/termb)/Math.log(1 + ir);
			}
			return np;
		}
		
		/////////////////////////////////////////////
		// get IY
		/////////////////////////////////////////////
		public static function comp_iy(np:Number, ir:Number, pmt:Number, pv:Number, fv:Number, pb:Number=0):Number {
			// test value  silver
			ir = 0.03;
			
			
			var tir:Number = ir; // default value
			var maxtries:Number = 400;
			var val:Number = 0;
			var oldval:Number = 0;
			var delta:Number = 0;
			var olddelta:Number = 0;
			if((fv == 0.0) && (pv == 0.0)) {
				tir = (pmt < 0)?-1.0:1.0;
			}
			else {
				var k:Number = 0;
				var solved:Boolean = false;
				do {
					var i:Number = 0;
					var j:Number = 0;
					var guess:Number = (k == 0)?ir:-ir;
					var gd:Number = guess * .5;
					if(gd == 0.0)
						gd = 1.0;
					do {
						guess += gd;
						if(guess != 0.0) {
							val = comp_fv(np,guess,pmt,pv,pb);
							delta = Math.abs(val-fv);
						}
						if(i > 0) { // old values not set on i == 0
							j++;
							//test match of absolute values and rate of change
							if((Math.abs(val-oldval) > 1e-8) || (delta > 1e-8)) {
								j = 0;
							}
							if(delta > olddelta) {
								gd *= -.5;
							}
						}
						oldval = val;
						olddelta = delta;
					}
					while((i++ < maxtries) && (j < 3));
					if(i < maxtries) {
						tir = guess;
						solved = true;
					}
				}
				while((k++ < 2) && !solved);
				if(!solved) {
					//Alert.show('can\'t calc..');
				}
			}
			return tir;
		}

	}
}